﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CheckTicket.Sample
{
    /// <summary>
    /// A base class for objects of which the properties must be observable.
    /// </summary>
    public class ObservableObject : INotifyPropertyChanged//, INotifyPropertyChanging
    {
        private readonly SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

        /// <summary>
        /// Occurs after a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Raises the PropertyChanged event if needed.
        /// </summary>
        /// <remarks>If the propertyName parameter
        /// does not correspond to an existing property on the current class, an
        /// exception is thrown in DEBUG configuration only.</remarks>
        /// <param name="propertyName">The name of the property that
        /// changed.</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (SynchronizationContext.Current == _synchronizationContext)
            {
                //如果操作发生在同一个线程中，不需要进行跨线程执行
                RaisePropertyChanged(propertyName);
            }
            else
            {
                if (_synchronizationContext != null)
                {
                    //如果不是发生在同一个线程中
                    //准确说来，这里是在一个非UI线程中，需要进行UI的更新所进行的操作
                    _synchronizationContext.Post(RaisePropertyChanged, propertyName);
                }
                else
                {
                    SynchronizationContext.Current?.Post(RaisePropertyChanged, propertyName);
                }
            }
        }

        private void RaisePropertyChanged(object state)
        {
            var handler = PropertyChanged;
            handler?.Invoke(this, new PropertyChangedEventArgs(state.ToString()));
        }
    }
}
